<?php

namespace App\Console\Commands;

use App\Enums\OrderStatus;
use App\Models\Agent;
use App\Models\AgentConfig;
use App\Models\Order;
use App\Services\ChargeContext;
use App\Services\OrderService;
use App\Services\YeepayService;
use Illuminate\Console\Command;
use Illuminate\Support\Arr;

class OrderCancelCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'order:cancel';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '自动取消过时未支付的订单';

    /**
     * Create a new command instance.
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle(OrderService $orderService, YeepayService $yeepayService, ChargeContext $chargeContext)
    {
        //手动锁定的订单
        while (true) {
            /** @var Order $order */
            $order = Order::query()
                ->where('order_status', OrderStatus::NOT_PAY)
                ->where('manual_lock_until', '<=', now())
                ->orderBy('id')
                ->first();

            if (!$order) {
                break;
            }
            $this->doCancel($chargeContext, $orderService, $order);
            $this->output->writeln(sprintf('cancel manual lock order: %s', $order->order_no));
        }

        $agents = Agent::query()->get();
        /** @var Agent $agent */
        foreach ($agents as $agent) {
            $orderLockMinutes = AgentConfig::getConfig($agent->id, AgentConfig::ORDER_LOCK_MINUTES, 10);
            $cancelTime = now()->subMinutes($orderLockMinutes);
            while (true) {
                //根据系统统一配置的锁单时间自动取消没有手动锁定的订单
                /** @var Order $order */
                $order = Order::query()
                    ->where('agent_id', $agent->id)
                    ->where('created_at', '<=', $cancelTime)
                    ->where('order_status', OrderStatus::NOT_PAY)
                    ->whereNull('manual_lock_until')
                    ->orderBy('id')
                    ->first();

                if (!$order) {
                    break;
                }

                $this->doCancel($chargeContext, $orderService, $order);
                $this->output->writeln(sprintf('[%s]cancel order: %s', $agent->name, $order->order_no));
            }
        }

        return Command::SUCCESS;
    }

    private function doCancel(ChargeContext $context, OrderService $orderService, Order $order)
    {
        $payment = $order->payment;
        if ($payment) {
            try {
                $context->initInstance(request()->agent_id);
                $orderInfo = $context->queryOrder($payment->out_order_no);
                //$orderInfo = $yeepayService->queryOrder($payment->out_order_no);
                $orderStatus = Arr::get($orderInfo, 'status');
                if ('PROCESSING' === $orderStatus) {
                    //$yeepayService->closeOrder($payment->out_order_no, Arr::get($orderInfo, 'uniqueOrderNo'));
                    $context->closeOrder($payment->out_order_no, Arr::get($orderInfo, 'uniqueOrderNo'));
                }
            } catch (\Exception $e) {
                $this->output->warning($e->getMessage());
            }
        }
        \DB::transaction(function () use ($order, $orderService) {
            if ($order->product) {
                $product = $order->product;
                $product->increment('left_count', $order->quantity);
                $product->decrement('sales_count', $order->quantity);

                $order->order_status = OrderStatus::AUTO_CANCEL;
                $order->save();

                $orderService->increaseCancelCount($order->user_id, $order->is_resale);
            }
        });
    }
}
